// src/utils/GIS.js
import { Map, View } from "ol";
import TileLayer from "ol/layer/Tile";
import VectorLayer from "ol/layer/Vector";
import LayerGroup from "ol/layer/Group.js";
import XYZ from "ol/source/XYZ";
import VectorSource from "ol/source/Vector";
import GeoJSON from "ol/format/GeoJSON";
import { fromLonLat } from "ol/proj";
import { Style, Stroke, Fill, Text, Icon } from "ol/style";
import Draw from "ol/interaction/Draw";
import { Circle as CircleStyle } from "ol/style";
import "ol/ol.css"; // 引入 OpenLayers 的样式
import { Feature } from "ol";
import { Point } from "ol/geom";



export class GIS {
  constructor(options = {}) {
    this.apiKey = options.apiKey || ""; // 天地图 API 密钥
    this.container = options.container || null; // 地图容器 DOM
    this.center = options.center || [107.2306393, 34.3645]; // 默认宝鸡
    this.zoom = options.zoom || 9; // 默认缩放级别
    this.projection = "EPSG:4326";
    this.map = null;
    this.geojsonLayer = null;
    this.drawLayer = null;
    this.drawInteraction = null;
    this.drawSource = null;
    this.featuresLayer = null; //图斑数据
    this.selectInteraction = null; // 添加选择交互
    this.layers = [];
    this.swipe = 0.5;
    this.swipeLayer = null;
    this.swipePosition = 0.5;
  }

  layerNameEmun = {
    FEATURE: "图斑数据",
    DRAW: "绘制图层",
    TDTIMAGE: "天地图影像",
    TDTVECTOR: "天地图注记",
  };

  layerTypeMap = {
    vector: ["vec", "cva"], // [矢量底图, 矢量注记]
    image: ["img", "cva"], // [影像底图, 影像注记]
    terrain: ["ter", "cta"], // [地形晕渲, 地形注记]
  };

  // 计算分辨率（用于缩放级别控制）
  getResolutionForZoom(zoom) {
    return 180 / (256 * Math.pow(2, zoom)); // EPSG:4326 近似分辨率
  }

  addVectorLayer(name) {
    let layer = new VectorLayer({
      source: new VectorSource(),
      properties: {
        name: name,
      },
    });
    this.layers.push(layer);
    this.map.addLayer(layer);
    return layer;
  }

  // 初始化地图
  initMap(layerType = "image") {
    if (!this.container) {
      throw new Error("缺少地图容器");
    }
    const matrixSet = "w";
    this.map = new Map({
      target:  this.container,
      layers: [
        // 底图
        new TileLayer({
          source: new XYZ({
            url: `http://t{0-7}.tianditu.gov.cn/${this.layerTypeMap[layerType][0]}_${matrixSet}/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&TILEMATRIXSET=w&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${this.apiKey}`,
            layer: this.layerTypeMap[layerType][0],
            matrixSet: matrixSet,
            style: "default",
            crossOrigin: "anonymous",
            format: "tiles",
            wrapX: true,
          }),
          properties: {
            name: this.layerNameEmun.TDTIMAGE,
            type: "base",
          },
        }),
        // 注记
        new TileLayer({
          source: new XYZ({
            url: `http://t{0-7}.tianditu.gov.cn/${this.layerTypeMap[layerType][1]}_${matrixSet}/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${this.apiKey}`,
            layer: this.layerTypeMap[layerType][1],
            matrixSet: matrixSet,
            style: "default",
            crossOrigin: "anonymous",
            format: "tiles",
            wrapX: true,
          }),
          properties: {
            name: this.layerNameEmun.TDTVECTOR,
            type: "base",
          },
        }),
      ],
      view: new View({
        center: this.center, //fromLonLat(this.center, this.projection),
        zoom: this.zoom,
        projection: this.projection,
        maxZoom: 17,
        minZoom: 1,
      }),
    });

    return this;
  }

  registerMapClick(callback) {
    if (!this.map) {
      return;
    }
    // 添加点击事件监听
    this.map.on("click", (event) => {
      this.map.forEachFeatureAtPixel(event.pixel, (feature, layer) => {
        let layername = layer.get("name");
        if (layername == this.layerNameEmun.FEATURE) {
          let attr = feature.getProperties();
          if (attr) {
            callback(feature.getProperties());
          }
        }
      });
    });
  }
  refresh(swipe) {
    console.log(this.swipe)
    this.swipe = swipe;
    this.map.render();
  }
  clearEvent(layer) {
   layer.on("prerender",function(){
    console.log("清空事件")
   })
   layer.on("postrender",function(){
    console.log("清空事件")
   })
    
  }
  initswipelayer(layer) {
    if (!layer) return;
    
    // 清除之前的卷帘效果
    if (this.swipeLayer) {
      this.clearEvent(this.swipeLayer);
    }

    this.swipeLayer = layer;
    
    // 添加卷帘效果
    layer.on('prerender', (event) => {
      const ctx = event.context;
      const width = ctx.canvas.width * this.swipePosition;
      
      ctx.save();
      ctx.beginPath();
      ctx.rect(0, 0, width, ctx.canvas.height);
      ctx.clip();
    });

    layer.on('postrender', (event) => {
      event.context.restore();
    });
  }

  // 更新卷帘位置
  updateSwipePosition(position) {
    this.swipePosition = position;
    if (this.swipeLayer) {
      this.swipeLayer.changed();
    }
  }

  // 清除卷帘事件
  clearEvent(layer) {
    if (layer) {
      layer.un('prerender', layer.getListeners('prerender')[0]);
      layer.un('postrender', layer.getListeners('postrender')[0]);
    }
    this.swipeLayer = null;
  }

  // 刷新地图
  refresh() {
    if (this.map) {
      this.map.render();
    }
  }

  createPolygonStyle(style, zoom = 10) {
    let feature_style;
    switch (style.type) {
      case "icon":
        let baseScale = style.baseScale || 1;
        let scale = baseScale * Math.pow(1.15, zoom - 10);
        feature_style = new Style({
          image: new Icon({
            anchor: [0.5, 1],
            scale: scale * 0.3,
            src: style.img,
          }),
        });

        break;
      case "polygon":
        feature_style = new Style({
          fill: new Fill({
            color: style.fillcolor || "rgba(0, 255, 0, 0.3)",
          }),
          stroke: new Stroke({
            color: style.strokeColor || "rgba(0, 255, 0, 0.3)",
            width: style.strokeWidth || 1,
          }),
        });
        break;
      case "line":
        feature_style = new Style({
          stroke: new Stroke({
            color: style.strokeColor || "rgba(0, 255, 0, 0.3)",
            width: style.strokeWidth || 1,
          }),
        });
        break;
    }
    if (style.text) {
      let text = new Text({
        text: style.text,
        font: "14px sans-serif",
        fill: new Fill({ color: style.textcolor | "black" }),
        // stroke: new Stroke({ color: textcolor, width: 2 }),
        overflow: true,
        placement: "point",
      });
      feature_style.setText(text);
    }
    return feature_style;
  }

  /**
   *
   * @param {*} url
   * @param {*} options {layerName,layerType,textfiled,style}
   */
  async loadGeoJSON(url, options) {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const geojsonData = await response.json();
    // 创建 GeoJSON format 实例
    const geojsonFormat = new GeoJSON();

    const source = new VectorSource({
      features: geojsonFormat.readFeatures(geojsonData),
      projection: this.projection,
    });
    let self = this;

    let layer = new VectorLayer({
      source,
      properties: {
        name: options.layerName,
        type: options.layerType,
      },

      style: (feature, resolution) => {
        let style = options.style;
        if (options.textfiled) {
          style.text = feature.get("name") || "";
        }
        let zoom = this.map.getView().getZoomForResolution(resolution);
        return self.createPolygonStyle(style, zoom);
      },
    });
    this.map.addLayer(layer);
  }

  getlayertype() {
    const layers = [];

    // 递归函数，处理图层和图层组
    function collectLayers(layer) {
      if (layer instanceof LayerGroup) {
        // 如果是图层组，递归获取其子图层
        layer.getLayers().forEach(collectLayers);
      } else {
        // 如果是普通图层，添加到结果数组
        layers.push(layer);
      }
    }

    // 获取地图的所有顶层图层/图层组
    this.map.getLayers().forEach(collectLayers);
    console.log(layers);

    return layers;
  }
  zoomToLayer(layer) {
    console.log(layer, this.map);
    // this.map.ex
  }

  loadGeoJSON1(url, options = {}) {
    if (!this.map) {
      throw new Error("地图未初始化，请先调用 initMap");
    }
    console.log("加载 GeoJSON:", url);
    const maxZoom = options.maxZoom || 3;
    const source = new VectorSource({
      url,
      format: new GeoJSON(),
      projection: this.projection,
    });

    fetch(url)
      .then((res) => {
        if (!res.ok) throw new Error(`HTTP 错误: ${res.status}`);
        return res.json();
      })
      .then((data) => console.log("GeoJSON 内容:", data))
      .catch((err) => console.error("无法访问 GeoJSON:", url, err));
    source.on("featuresloadstart", () => console.log("开始加载 GeoJSON 特征"));
    source.on("featuresloadend", () => {
      const features = source.getFeatures();
      console.log("GeoJSON 加载成功，特征数量:", features.length);
      if (features.length === 0) {
        console.warn("GeoJSON 文件为空");
      }
    });
    source.on("error", (e) => {
      console.error("GeoJSON 加载失败:", url, e);
    });

    this.geojsonLayer = new VectorLayer({
      source,
      maxResolution: this.getResolutionForZoom(maxZoom),
      style: (feature, resolution) => {
        const name = feature.get("name") || "未知";
        console.log("应用样式，特征名称:", name);
        return new Style({
          fill: new Fill({
            color: "rgba(0, 255, 0, 0.3)",
          }),
          stroke: new Stroke({
            color: "green",
            width: 2,
          }),
          text: new Text({
            text: name,
            font: "14px sans-serif",
            fill: new Fill({ color: "white" }),
            stroke: new Stroke({ color: "white", width: 2 }),
            overflow: true,
            placement: "point",
          }),
        });
      },
    });

    this.map.addLayer(this.geojsonLayer);
    console.log(
      "GeoJSON 图层已添加，当前图层数量:",
      this.map.getLayers().getLength()
    );
    return this;
  }
  // 设置中心点
  setCenter(lonLat, zoom) {
    this.map.getView().setCenter(fromLonLat(lonLat, this.projection));
    if (zoom !== undefined) {
      this.map.getView().setZoom(zoom);
    }
  }

  // 设置缩放级别
  setZoom(zoom) {
    this.map.getView().setZoom(zoom);
  }

  // 获取当前缩放级别
  getZoom() {
    return this.map.getView().getZoom();
  }

  // 清除 GeoJSON 图层
  clearGeoJSON() {
    if (this.geojsonLayer) {
      this.map.removeLayer(this.geojsonLayer);
      this.geojsonLayer = null;
    }
  }

  // 初始化绘制图层
  initDrawLayer() {
    if (!this.drawLayer) {
      this.drawSource = new VectorSource();
      this.drawLayer = new VectorLayer({
        source: this.drawSource,
        style: new Style({
          fill: new Fill({
            color: "rgba(255, 255, 255, 0.2)",
          }),
          stroke: new Stroke({
            color: "#ffcc33",
            width: 2,
          }),
          image: new CircleStyle({
            radius: 7,
            fill: new Fill({
              color: "#ffcc33",
            }),
          }),
        }),
      });
      this.drawLayer.set("name", this.layerNameEmun.DRAW);
      this.drawLayer.set("type", "temp");
      this.map.addLayer(this.drawLayer);
    }
  }

  // 开启绘制功能
  startDraw(type, callback) {
    this.stopDraw();
    this.initDrawLayer();

    // 创建绘制交互
    this.drawInteraction = new Draw({
      source: this.drawSource,
      type: type, // 'Point', 'LineString', 'Polygon', 'Circle'
    });

    // 添加绘制完成的事件监听
    this.drawInteraction.on("drawend", (event) => {
      const feature = event.feature;
      console.log("绘制完成:", feature);
      // 创建 WKT 格式实例
      const wktFormat = new WKT();
      // 将 Feature 转换为 WKT 字符串
      const wktString = wktFormat.writeFeature(feature);
      callback(wktString);
    });

    this.map.addInteraction(this.drawInteraction);
  }

  // 停止绘制
  stopDraw() {
    if (this.drawInteraction) {
      this.map.removeInteraction(this.drawInteraction);
      this.drawInteraction = null;
    }
  }

  // 清除绘制的内容
  clearDraw() {
    if (this.drawSource) {
      this.drawSource.clear();
    }
  }

  // 获取绘制的要素
  getDrawFeatures() {
    return this.drawSource ? this.drawSource.getFeatures() : [];
  }

  // 销毁地图
  destroy() {
    this.stopDraw();
    if (this.drawLayer) {
      this.map.removeLayer(this.drawLayer);
      this.drawLayer = null;
    }
    if (this.map) {
      this.map.setTarget(null);
      this.map = null;
    }
  }

  // 添加要素渲染方法
  renderFeatures(features, callback) {
    if (!this.featuresLayer) {
      this.featuresLayer = new VectorLayer({
        source: new VectorSource(),
        style: (feature) => {
          const type = feature.get("ty");
          return this.getFeatureStyle(type);
        },
      });
      this.featuresLayer.set("name", this.layerNameEmun.FEATURE);
      this.featuresLayer.set("type", "important");
      this.map.addLayer(this.featuresLayer);
    }

    // 移除旧的点击交互
    if (this.selectInteraction) {
      this.map.removeInteraction(this.selectInteraction);
    }

    const source = this.featuresLayer.getSource();
    source.clear();

    features.forEach((item) => {
      const feature = new Feature({
        geometry: new Point([item.x, item.y]),
        ...item,
      });

      source.addFeature(feature);
    });
    this.registerMapClick(callback);
  }

  // 获取不同类型要素的样式
  getFeatureStyle(type) {
    const styles = {
      dj: new Style({
        image: new CircleStyle({
          radius: 8,
          fill: new Fill({ color: "#FF4B4B" }),
          stroke: new Stroke({ color: "#ffffff", width: 2 }),
        }),
      }),
      kf: new Style({
        image: new CircleStyle({
          radius: 8,
          fill: new Fill({ color: "#4B8BFF" }),
          stroke: new Stroke({ color: "#ffffff", width: 2 }),
        }),
      }),
      3: new Style({
        image: new CircleStyle({
          radius: 8,
          fill: new Fill({ color: "#44D7B6" }),
          stroke: new Stroke({ color: "#ffffff", width: 2 }),
        }),
      }),
    };
    return styles[type] || styles[1];
  }

  // 更新图层可见性
  updateLayerVisibility(layer) {
    if (!layer) return;
    
    // 获取所有图层
    const layers = this.getlayertype();
    
    // 先隐藏所有图层
    layers.forEach(l => {
      if (l.get('type') !== 'base') {
        l.setVisible(false);
      }
    });
    
    // 显示选中的图层
    layer.setVisible(true);
  }
}
